package wiiusej;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Vector;
import java.util.concurrent.BlockingQueue;

import org.apache.log4j.Logger;

import wiiusej.apptest.statistics.performance.PerformanceUnit;
import wiiusej.apptest.statistics.performance.Track;
import wiiusej.wiiusejevents.GenericEvent;
import wiiusej.wiiusejevents.wiiuseapievents.StatusEvent;
import wiiusej.wiiusejevents.wiiuseapievents.WiiUseApiEvent;
import wiiusej.wiiusejevents.wiiuseapievents.WiimoteEvent;

public class DeliveryAssistant implements Runnable{

	//Logger 
	private static Logger fileLogger;
	
	//COM QUEUES
	private static HashMap<Integer, BlockingQueue<GenericEvent>> wiimoteComChannels;
	private BlockingQueue<WiiUseApiEvent> toNetListener;
	private BlockingQueue<Track> toPerformanceController;
	
	private Vector<WiiUseApiEvent> events;	
	private long genericPacketCounter;
	
	
	
	public DeliveryAssistant(HashMap<Integer, BlockingQueue<GenericEvent>> wiimoteComChannels, 
			BlockingQueue<WiiUseApiEvent> toNetListener, BlockingQueue<Track> toPerformanceController2, 
			Vector<WiiUseApiEvent> events, long genericPacketCounter, Logger fileLogger){
		
		this.events = (Vector<WiiUseApiEvent>) events.clone();
		this.genericPacketCounter = genericPacketCounter;
		this.wiimoteComChannels = wiimoteComChannels;
		this.toNetListener = toNetListener;
		this.toPerformanceController = toPerformanceController2;
		
		this.fileLogger = fileLogger;
	}
	
	
	public void run() {
		
		SimpleDateFormat tsFormat = new SimpleDateFormat("mm:ss:SS");
		
		long start = System.currentTimeMillis();
		
		
		//deal with events gathered in Wiiuse API
		for (WiiUseApiEvent evt : events) {
			
			//genericPacketCounter++;
			
			/*
			fileLogger.info("Event Received: " + evt.getEventType() 
					+ " From: " + evt.getWiimoteId() 
					+ " at: " + tsFormat.format(System.currentTimeMillis()) + 
					" #: " + genericPacketCounter);
				*/		
			
			if (evt.getWiimoteId() != -1) {// event filled					
				
				switch(evt.getEventType()){
				
				case WiiUseApiEvent.STATUS_EVENT:
					
					fileLogger.info("Status Event Received - Sudando!");
					//statusEventCounter++;										
					evt.setRefNumber(genericPacketCounter);
					StatusEvent status = (StatusEvent) evt;
					
					
					//fileLogger.info(status);
					//fileLogger.info("*********** Sending Status info to NetListener: " + genericPacketCounter);
					fileLogger.info("");
					//notifyNetListener(evt);
					break;
				
				default: 
					fileLogger.info("Notifying the listeners");
					notifyWiiUseApiListener(evt);
					break;
				}					
				
			} else {
				fileLogger.error("NON-VALID WIIMOTE ID");
			}
		}
		
		events.clear();
		
		
		
	}
	
	
	/**
	 * Notify WiiUseApiListeners that an event occured.
	 * 
	 * @param evt
	 *            GenericEvent occured
	 */
	private void notifyWiiUseApiListener(WiiUseApiEvent evt) {
		
		//String myName = Integer.toString(evt.getWiimoteId());
		SimpleDateFormat tsFormat = new SimpleDateFormat("mm:ss:SS");
		if (evt.getEventType() == WiiUseApiEvent.GENERIC_EVENT) {
			
			Timestamp ts = new Timestamp (System.currentTimeMillis());
			
			WiimoteEvent event = ((WiimoteEvent) evt);
			
			
			/*
			HashMap<String, Timestamp> timeStamp;		
			Timestamp ts = new Timestamp (System.currentTimeMillis());
			timeStamp = ((WiimoteEvent) evt).getMotionSensingEvent().getTimeStamp();
			
			timeStamp = new HashMap<String, Timestamp>();
			timeStamp.put(myName,ts);
			
			((WiimoteEvent) evt).getMotionSensingEvent().setTimeStamp(timeStamp);
			((WiimoteEvent) evt).getMotionSensingEvent().setTime(ts);
			*/
			
			event.setTime(ts);
			fileLogger.debug("PacketTime: " + tsFormat.format(event.getTime()));
			
			
			//((WiimoteEvent) evt).getMotionSensingEvent().setTime(ts);
			
			//set refNumber		
			//genericPacketCounter++;
			//evt.setRefNumber(genericPacketCounter);
			
			
			//fileLogger.info("New reference Number: " + genericPacketCounter + 
				//	" PacketNumber: " + evt.getRefNumber());		
			
			//sendToPerformanceController(evt);
			
			
		}
		
		
		
		//Select the channel regarding the wiimoteID
		BlockingQueue<GenericEvent> q = wiimoteComChannels.get(evt.getWiimoteId());
		
		if( q !=  null){
			try {				
				q.put(evt);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}			
			
		}else{
			fileLogger.info("ERROR finding comunucation channel. Wiimote: " + evt.getWiimoteId() + 
					" does NOT exists");
		}		
		
	}
	
	private void notifyNetListener(WiiUseApiEvent evt) {
		
		try {				
			toNetListener.put(evt);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}	
		
	}
	
	/*
	private void sendToPerformanceController(WiiUseApiEvent evt) {
		SimpleDateFormat tsFormat = new SimpleDateFormat("mm:ss:SS");
		Timestamp time = new Timestamp(System.currentTimeMillis());
		//fileLogger.debug("sendToPerformanceController: " + tsFormat.format(time));
		
		
		PerformanceUnit unitReport = new PerformanceUnit(evt.getWiimoteId(), evt.getRefNumber(), 
				time);
		
		try {
			toPerformanceController.put(unitReport);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}*/

}
